/**
 * @file port_sys.c
 * @author lijingjie (lijingjie@pthyidh.com)
 * @brief
 * @version 0.1
 * @date 2024-11-01
 *
 * @copyright Copyright (c) 2024 by 深圳市鹏天微智能科技有限公司, All Rights Reserved.
 *
 */

/* ==================== [Includes] ========================================== */

#include "pt3220.h"
#include "drvs.h"

#include "xf_sys.h"
#include "xf_init.h"

#include "port_common.h"
#include "port_log.h"

/* ==================== [Defines] =========================================== */

/* ==================== [Typedefs] ========================================== */

/* ==================== [Static Prototypes] ================================= */

/* ==================== [Static Variables] ================================== */

static uint64_t s_ticks = 0;
static uint16_t s_sys_rst_reason = 0;

/* ==================== [Macros] ============================================ */

/* ==================== [Global Functions] ================================== */

// 系统预初始化，在 main 函数前调用
void sys_pre_init(void)
{
    SYS_CLK_ALTER();

    iwdt_disable();

    s_sys_rst_reason = rstrsn();

    uart_log_init();
    char buffer[20];
    int len = snprintf(buffer, sizeof(buffer), "Start(0x%X)\n\n", s_sys_rst_reason);
    if (len > 0)
    {
        buffer[len] = '\0';
        uart_log_send(buffer, len, NULL);
    }

    GLOBAL_INT_START();
}

uint16_t sys_rst_reason_get(void)
{
    return s_sys_rst_reason;
}


xf_err_t xf_sys_watchdog_enable(void)
{
    iwdt_conf(32768); // 1s
    return XF_OK;
}

xf_err_t xf_sys_watchdog_disable(void)
{
    iwdt_conf(0);
    return XF_OK;
}

xf_err_t xf_sys_watchdog_kick(void)
{
    iwdt_feed();
    return XF_OK;
}

void xf_sys_reboot(void)
{
    NVIC_SystemReset();
}

xf_err_t xf_sys_interrupt_enable(void)
{
    GLOBAL_INT_START();
    return XF_OK;
}

xf_err_t xf_sys_interrupt_disable(void)
{
    GLOBAL_INT_STOP();
    return XF_OK;
}

/* ==================== [Static Functions] ================================== */

void SysTick_Handler(void)
{
    ++s_ticks;
}

static void systick_timer_init(uint32_t tick_us)
{
    uint8_t clk = rcc_sysclk_get();

    if (clk > SYS_CLK_HSI) {
        return ; // 主频太小
    }

    // Calculate the total number of ticks required for the desired tick_time (in microseconds)
    uint32_t total_ticks = (SYS_GET_CLOCK() / 1000000) * tick_us; // 1us
    SysTick_Config(total_ticks);
}

static xf_us_t _port_xf_sys_get_us(void)
{
    return ((s_ticks * 1000) + SysTick->VAL * 1000000 / SYS_GET_CLOCK());
}

static int port_sys_init()
{
    systick_timer_init(1000); // 100ms中断
    xf_sys_time_init(_port_xf_sys_get_us);
    return XF_OK;
}

XF_INIT_EXPORT_BOARD(port_sys_init);
